package com.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.entity.Post;
import com.entity.Role;
import com.entity.Users;
import com.entity.UsersPersonal;
import com.service.UsersPersonalService;
import com.service.UsersService;
import com.utils.DataResult;
import com.utils.handleToken;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.server.Session;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 账户表 前端控制器
 * </p>
 *
 * @author Damon
 * @since 2021-04-26
 */
/*@RestController
@RequestMapping("/users")
public class UsersController {

}*/
@RestController
@CrossOrigin
@RequestMapping("/users")
//@Api(value = "UsersController", tags = {"用户相关接口"})
public class UsersController {

    @Autowired
    private UsersService usersService;

    @Autowired
    private UsersPersonalService usersPersonalService;
    /**//**//**//** 个人/企业用户注册 *//**//**//**/
    @PostMapping("/register")
    @ApiOperation(value = "个人/企业/公司用户注册", notes = "个人/企业/公司用户注册", httpMethod = "POST")

    public DataResult register ( @RequestBody Users user) {
        // 参数为空校验
        if(Objects.equals(user.getUserAccount(), "") || Objects.equals(user.getPassword(), "") || Objects.equals(user.getType(), ""))
            return DataResult.failed().message("传入的账户/密码为空，或账户类型不是个人/企业用户/公司用户");
        // 账户和密码长度校验
        if(user.getUserAccount().length() < 3 || user.getPassword().length() < 3)
            return DataResult.failed().message("账户或密码长度小于3位，请重新输入！");
        // 校验用户是否存在
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.select("user_account","created_time").eq("user_account", user.getUserAccount());
        List<Users> users = usersService.list(wrapper);
        if(users.size() != 0) return DataResult.failed().message("用户ID已存在，请重新输入！");
        if (user.getType()==4) return DataResult.failed().message("你不能注册该类型账户！");
        // 创建用户
        Users new_user = new Users();
        new_user.setUserAccount(user.getUserAccount());
        new_user.setPassword(user.getPassword());
        new_user.setType(Integer.valueOf(user.getType()));
        Date date = new Date();
        new_user.setCreatedTime(date);
        boolean flag = usersService.save(new_user);
        if (flag) {
            Users regUser = usersService.getOne(wrapper);
            // 如果是个人自动注册创建空信息表
            if(Objects.equals(user.getType(), "0")){
                UsersPersonal newinfo = new UsersPersonal();
                newinfo.setUserAccount(user.getUserAccount());
                usersPersonalService.save(newinfo);
            }
            return DataResult.finished().data("data", regUser).message("用户注册成功！");
        } else {
            return DataResult.failed().message("用户注册失败!");
        }
    }
    /**//**//**//**//**//** 所有用户登录 *//**//**//**//**//**//**/
    @PostMapping("login")
    @ApiOperation(value = "所有用户登录", notes = "所有用户登录", httpMethod = "POST")
    public DataResult login ( @RequestBody Users user) {
        // 参数为空校验
        if(Objects.equals(user.getUserAccount(), "") || Objects.equals(user.getPassword(), ""))
            return DataResult.failed().message("传入的账户/密码为空！");
        // 账户和密码长度校验
        if(user.getUserAccount().length() < 3 || user.getPassword().length() < 3)
            return DataResult.failed().message("账户或密码长度小于3位，请重新输入！");
        if(Objects.equals(user.getType(),""))
            return DataResult.failed().message("账户类型不正确");
        // 校验用户是否正确
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("user_account", user.getUserAccount());
        List<Users> users = usersService.list(wrapper);
        // 先判断用户ID是否存在
        if(users.size() == 0) {
            return DataResult.failed().message("账户错误，请重新输入");
        } else{
            // 存在后判断对应的密码是否正确
            if(!Objects.equals(users.get(0).getPassword(), user.getPassword())){
                return DataResult.failed().message("密码错误，请重新输入");
            }else{
                //判断用户类型是否正确，数据库为int类型需要转换
                if (!Objects.equals(users.get(0).getType(),user.getType())){
                    return DataResult.failed().message("账户类型错误，请重新输入");
                }
            }
        }
        Users logUser = users.get(0);
        Date created_time = new Date();
        String token = handleToken.createToken();
        logUser.setToken(token);
        logUser.setTokenTime(created_time);
        boolean flag = usersService.updateById(logUser);
        if (flag) {
            wrapper.select("user_account","token","created_time");
            Users regUser = usersService.getOne(wrapper);
            return DataResult.finished().data("data", regUser).message("用户登录成功！");
        } else {
            return DataResult.failed().message("用户登录失败！");
        }
    }



    /**//**//**//** 用户注销*//**//**//**/
    @RequestMapping("/loginout")
    @ApiOperation(value = "所有用户退出", notes = "所有用户退出", httpMethod = "POST")
    public DataResult loginout (Users user,HttpSession session) {
        session.removeAttribute("user");
        return DataResult.finished().message("用户退出成功！");
    }
    /**//**//** 所有用户修改密码 *//**//**//**/
    @PostMapping("/changePwd")
    @ApiOperation(value = "所有用户修改密码", notes = "所有用户修改密码", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userAccount", value = "用户的账户名", required = true, dataType = "string"),
            @ApiImplicitParam(name = "token", value = "验证用户登录状态的校验码", required = true, dataType = "string"),
            @ApiImplicitParam(name = "oldpsw", value = "用户原来的密码", required = true, dataType = "string"),
            @ApiImplicitParam(name = "newpsw", value = "用户新的密码", required = true, dataType = "string")})
    public DataResult changePwd ( String userAccount, String oldpsw, String newpsw, String token) {
        // 参数为空校验
        if(Objects.equals(userAccount, "") || Objects.equals(oldpsw, "") || Objects.equals(newpsw, "") || Objects.equals(token, ""))
            return DataResult.failed().message("传入参数有误");
        // 账户和密码长度校验
        if(userAccount.length() < 5 || oldpsw.length() < 5 || newpsw.length() < 5)
            return DataResult.failed().message("账户或密码长度小于5位，请重新输入！");
        // 判断输入的新旧密码是否相同
        if(Objects.equals(oldpsw, newpsw)) return DataResult.failed().message("输入的新旧密码相同，请重新输入！");
        // 校验token是否正确，不正确直接调用untoken状态码返回
        Users logUser = handleToken.checkToken(userAccount, token);
        if(logUser == null) return DataResult.untoken();
        // 验证旧密码是否正确
        if(!Objects.equals(logUser.getPassword(), oldpsw)){
            return DataResult.failed().message("账户或密码错误，请重新输入");
        }
        // 正确的话更新新密码
        logUser.setPassword(newpsw);
        boolean flag = usersService.updateById(logUser);
        if (flag) {
            QueryWrapper<Users> wrapper = new QueryWrapper<>();
            wrapper.eq("user_account", userAccount);
            wrapper.select("user_account","token","created_time");
            Users regUser = usersService.getOne(wrapper);
            return DataResult.finished().data("data", regUser).message("用户密码修改成功！");
        } else {
            return DataResult.failed().message("用户密码修改失败！");
        }
    }

    /**//**//**//** 企业管理员查询用户列表 *//**//**//**/
    @PostMapping("/query")
    @ApiOperation(value = "企业管理员查询用户列表", notes = "企业管理员查询用户列表", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userAccount", value = "用户创建的ID", required = true, dataType = "string"),
            @ApiImplicitParam(name = "keywords", value = "查询的关键词，为空则为查询全部", dataType = "string"),
            @ApiImplicitParam(name = "token", value = "验证用户登录状态的校验码", required = true, dataType = "string")})
    public DataResult query (String userAccount, String keywords, String token) throws Exception {
//        String company_key = "1";
        // 校验token是否正确，不正确直接调用untoken状态码返回
        Users logUser = handleToken.checkToken(userAccount, token);
        if(logUser == null) return DataResult.untoken();
        // todo：这里要有权限拦截，普通权限直接拒绝查询，管理员权限只能查找对应企业的
        // 定义模糊查询的字段
        QueryWrapper<UsersPersonal> wrapper = new QueryWrapper<>();
        QueryWrapper<Users> wrapper2 = new QueryWrapper<>();
        if(Objects.equals(keywords, "")){
            // .select("user_account","created_time")
            wrapper2.eq("company_key", logUser.getCompanyKey());
        } else {
            // 模糊在user_personal表中查询字段
            wrapper.like("user_account", keywords).or().like("nickname",keywords).or().like("realname",keywords);
        }
        // 把模糊匹配的结果，同企业符合要求的结果放在一起
        List<UsersPersonal> perusers = usersPersonalService.list(wrapper);
        List<Users> users = usersService.list(wrapper2);
        // 定义返回的数据列表
        List<Map<String, Object>> retDataList = new ArrayList<Map<String,Object>>();
        for (UsersPersonal peruser : perusers) {
            String account = peruser.getUserAccount();
            for (Users user : users) {
                if (Objects.equals(user.getUserAccount(), account)) {
                    Map<String, Object> tempMap = new HashMap<>();
                    tempMap.put("user_key", user.getUsersKey());
                    tempMap.put("created_time", peruser.getCreatedTime());
                    tempMap.put("user_account", peruser.getUserAccount());
                    tempMap.put("nickname", peruser.getNickname());
                    tempMap.put("realname", peruser.getRealname());
                    tempMap.put("face", peruser.getFace());
                    tempMap.put("sex", peruser.getSex());
                    retDataList.add(tempMap);
                }
            }
        }
        return DataResult.finished().data("data", retDataList).message("查询所有账户信息成功");
    }


    /**//**//**//*@ApiOperation(value = "企业管理员删除用户", notes = "企业管理员删除用户", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userAccount", value = "用户的账户名", required = true, dataType = "string"),
            @ApiImplicitParam(name = "token", value = "验证用户登录状态的校验码", required = true, dataType = "string")})*//**//**//**//*
    public DataResult delete ( String userAccount, String token) {
        // 参数为空校验
        if(Objects.equals(userAccount, "") || Objects.equals(token, ""))
            return DataResult.failed().message("传入参数有误");
        // 校验token是否正确，不正确直接调用untoken状态码返回
        Users logUser = handleToken.checkToken(userAccount, token);
        if(logUser == null) return DataResult.untoken();
        // todo:权限控制问题
        logUser.setIsdelete(true);
        boolean flag = usersService.updateById(logUser);
        // 返回删除的用户
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("user_account", userAccount);
        wrapper.select("user_account","created_time");
        Users regUser = usersService.getOne(wrapper);
        return DataResult.finished().data("data", regUser).message("用户删除成功！");
    }
/*@RestController
@RequestMapping("/users")
@Api(value = "UsersController", tags = {"个人/专家用户登录注册接口"})
public class UsersController {
    @Autowired
    private UsersService usersService;

    *//** 注册个人/专家用户账户
     *//*
    @PostMapping("reg") // Post方法 /users/reg
    @ApiOperation(value = "注册个人/专家用户账户", notes = "注册个人/专家用户账户", httpMethod = "POST")
    // GET请求会直接在函数括号里面跟参数，并且写在外面写@ApiImplicitParams注解
    // POST请求需要写@RequestBody请求体，通过参数对象来传参数，一定要注意否则前端Vue+axios接收不了参数
    public DataResult reg(
            @ApiParam(name = "users", value = "个人/专家账户对象", required = true)
            @RequestBody Users users)
    {
        // 设置添加成功的返回标志
        boolean flag = usersService.save(users); //INSERT

        if (flag) {
            // 成功返回数据
            return DataResult.finished().message("用户注册成功！");
        } else {
            // 失败返回数据
            return DataResult.failed().message("用户注册失败！");
        }
    }*/

    /**//**//**//** 管理员删除用户 *//**//**//**/
    @GetMapping("/del") // Get方法
    @ApiOperation(value = "删除用户", notes = "删除用户", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userid", value = "用户唯一标示", required = true, dataType = "string")})
    // GET请求会直接在函数括号里面跟参数，并且写在外面写@ApiImplicitParams注解
    // POST请求需要写@RequestBody请求体，通过参数对象来传参数，一定要注意否则前端Vue+axios接收不了参数
    public DataResult del(String userid) {
        // 设置删除成功的返回标志
        boolean flag = usersService.removeById(userid); // 删除

        if (flag) {
            // 成功返回数据
            return DataResult.finished().message("用户删除成功！");
        } else {
            // 失败返回数据
            return DataResult.failed().message("用户删除失败！");
        }
    }

    /**//**//**//** 查找 *//**//**//**/
    @RequestMapping("/list")
    @ApiOperation(value = "查找用户", notes = "查找用户", httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "token", value = "登录的token值", required = true, dataType = "string")})
    // GET请求会直接在函数括号里面跟参数，并且写在外面写@ApiImplicitParams注解
    // POST请求需要写@RequestBody请求体，通过参数对象来传参数，一定要注意否则前端Vue+axios接收不了参数
    public List<Users> list(String token){
        return usersService.selectusers(token);
    }


}

